{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 作业(⼀)实现 KNN 算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入Python库\n",
    "import numpy as np\n",
    "from collections import Counter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义计算距离和预测准确率等基础函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def distance(a, b, p=2):\n",
    "    '''计算样本之间的明可夫斯基距离，默认计算欧拉距离（p=2）'''\n",
    "    return np.sum(np.abs(a - b) ** p) ** (1 / p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def accuracy_score(y, y_predict):\n",
    "    '''计算预测准确率'''\n",
    "\n",
    "    assert y.shape[0] == y_predict.shape[0], 'y与y_predict长度需要相同'\n",
    "\n",
    "    return sum(y == y_predict) / len(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 封装kNN算法类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class KNeighbourClassifier():\n",
    "    '''kNN（k近邻算法）分类器'''\n",
    "    def __init__(self, k=5, p=2):\n",
    "        '''初始化kNN算法参数：k,p'''\n",
    "        \n",
    "        assert k > 0, 'k需要大于0'\n",
    "        assert p > 0, 'p需要大于0'\n",
    "        \n",
    "        self.k = k;\n",
    "        self.p = p\n",
    "\n",
    "    def fit(self, X_train, y_train):\n",
    "        '''通过样本训练模型（保存训练样本）'''\n",
    "        \n",
    "        assert self.k <= y_train.shape[0], '总的样本数需要大于或等于k'\n",
    "        assert X_train.shape[0] == y_train.shape[0], 'X_train中样本数量需要与y_train的数量相同'\n",
    "\n",
    "        self.X_train = X_train\n",
    "        self.y_train = y_train\n",
    "\n",
    "    def predict(self, X_predict):\n",
    "        '''预测测试样本集分类'''\n",
    "        assert self.X_train.shape[1] == X_predict.shape[1], '预测的特征数量需要等于样本的特征数量'\n",
    "\n",
    "        return np.array([self._predict(x) for x in X_predict])\n",
    "\n",
    "    def _predict(self, x):\n",
    "        '''预测测试样本分类'''\n",
    "        #计算测试样本与训练样本集每个样本的距离\n",
    "        distances = [distance(item, x, p=self.p) for item in self.X_train]\n",
    "        #样本距离排序，取距离最近的k个训练样本\n",
    "        nearest = np.argsort(distances)[:self.k]\n",
    "        k_labels = self.y_train[nearest]\n",
    "\n",
    "        #返回距离最近的k个训练样本归属最多的分类\n",
    "        return Counter(k_labels).most_common(1)[0][0]\n",
    "        \n",
    "    def score(self, X_test, y_test):\n",
    "        '''计算kNN算法的预测准确率'''\n",
    "        #预测测试样本集分类\n",
    "        y_predict = self.predict(X_test)\n",
    "\n",
    "        #计算预测准确率：预测分类与实际分类对比\n",
    "        return accuracy_score(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义拆分训练集与测试集函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train_test_split(X, y, test_size=0.25, seed=None):\n",
    "    '''使用留出法拆分训练集与测试集'''\n",
    "\n",
    "    assert X.shape[0] == y.shape[0], \"X中样本数量需要等于y中的标签数量\"\n",
    "\n",
    "    assert 0 <= test_size <= 1, \"test_size有效范围为0到1之间\"\n",
    "\n",
    "    #如果传入随机数种子，则设置随机数种子\n",
    "    if seed:\n",
    "        np.random.seed(seed)\n",
    "\n",
    "    #样本集随机打乱顺序\n",
    "    shuffle = np.random.permutation(len(X))\n",
    "\n",
    "    #计算测试集大小\n",
    "    size = int(len(X) * test_size)\n",
    "\n",
    "    #划分训练集和测试集索引\n",
    "    test_index = shuffle[:size]\n",
    "    train_index = shuffle[size:]\n",
    "\n",
    "    #拆分训练集和测试集\n",
    "    X_train = X[train_index]\n",
    "    y_train = y[train_index]\n",
    "\n",
    "    X_test = X[test_index]\n",
    "    y_test = y[test_index]\n",
    "\n",
    "    #返回训练集和测试集\n",
    "    return X_train, X_test, y_train, y_test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 加载鸢尾花数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>萼片长(cm)</th>\n",
       "      <th>萼片宽(cm)</th>\n",
       "      <th>花瓣长(cm)</th>\n",
       "      <th>花瓣宽(cm)</th>\n",
       "      <th>分类</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.1</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.9</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4.7</td>\n",
       "      <td>3.2</td>\n",
       "      <td>1.3</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4.6</td>\n",
       "      <td>3.1</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5.0</td>\n",
       "      <td>3.6</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   萼片长(cm)  萼片宽(cm)  花瓣长(cm)  花瓣宽(cm)  分类\n",
       "0      5.1      3.5      1.4      0.2   0\n",
       "1      4.9      3.0      1.4      0.2   0\n",
       "2      4.7      3.2      1.3      0.2   0\n",
       "3      4.6      3.1      1.5      0.2   0\n",
       "4      5.0      3.6      1.4      0.2   0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "#加载鸢尾花数据集\n",
    "df = pd.read_excel('data/iris.xlsx')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(150, 4)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#切片鸢尾花数据集的参数列\n",
    "X = df.values[:,:4]\n",
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(150,)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#切片鸢尾花数据集的分类列\n",
    "y = df.values[:,-1]\n",
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "#展示鸢尾花数据集萼片长与萼片宽参数的分布\n",
    "plt.scatter(X[y==0,0],X[y==0,1],color='r')\n",
    "plt.scatter(X[y==1,0],X[y==1,1],color='g')\n",
    "plt.scatter(X[y==2,0],X[y==2,1],color='b')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#展示鸢尾花数据集花瓣长与花瓣宽参数的分布\n",
    "plt.scatter(X[y==0,2],X[y==0,3],color='r')\n",
    "plt.scatter(X[y==1,2],X[y==1,3],color='g')\n",
    "plt.scatter(X[y==2,2],X[y==2,3],color='b')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 用鸢尾花数据集测试kNN算法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第一次测试(test_size=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(120, 4)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将鸢尾花数据集拆分为训练集与测试集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, seed=100)\n",
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(30, 4)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2., 0., 2., 0., 2., 2., 0., 0., 2., 0., 0., 2., 0., 0., 2., 1., 1.,\n",
       "       1., 2., 2., 2., 0., 2., 0., 1., 2., 1., 0., 1., 2.])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#构建kNN算法对象\n",
    "knn_clf = KNeighbourClassifier()\n",
    "#通过训练样本集训练模型\n",
    "knn_clf.fit(X_train, y_train)\n",
    "#通过测试样本集预测样本分类\n",
    "y_predict = knn_clf.predict(X_test)\n",
    "y_predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#直接计算kNN算法的预测准确率\n",
    "knn_clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第二次测试(test_size=0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(113, 4)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将鸢尾花数据集拆分为训练集与测试集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, seed=100)\n",
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(37, 4)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.972972972972973"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#构建kNN算法对象\n",
    "knn_clf = KNeighbourClassifier()\n",
    "#通过训练样本集训练模型\n",
    "knn_clf.fit(X_train, y_train)\n",
    "#直接计算kNN算法的预测准确率\n",
    "knn_clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第三次测试(test_size=0.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(105, 4)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将鸢尾花数据集拆分为训练集与测试集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, seed=100)\n",
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9777777777777777"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#构建kNN算法对象\n",
    "knn_clf = KNeighbourClassifier()\n",
    "#通过训练样本集训练模型\n",
    "knn_clf.fit(X_train, y_train)\n",
    "#直接计算kNN算法的预测准确率\n",
    "knn_clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
